package com.wisenet.test;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ThreadPoolExecutorGetMovie {
	// TODO 先确定电影总页数
	private static int ALL_PAGES = 10;
	// TODO 分页电影链接
	private static String URL_PAGES = "https://www.qiyidy.net/frim/15";
//	private static String URL_PAGES = "http://www.kdyy.cc/search.php?searchtype=5&tid=1&area=%E9%9F%A9%E5%9B%BD&page=";
	// 所有分页电影链接
	private static List<String> linkList = new ArrayList<>();
	// 所有电影详情
	private static List<Map<String, String>> movieList = new ArrayList<>();

	/**
	 * 获取所有电影详情
	 * @return
	 */
	public static List<Map<String, String>> getMovieInfoList() {
		// 获取所有分页电影链接
		getAllPageLinksExecutor();
		if(linkList.size() > 0) {
			System.out.println("分页电影链接总数：" + linkList.size());
			for(String link : linkList) {
				System.out.println(link);
			}
			// 获取所有电影详情
			getAllMoviesInfoExecutor();
		}
		// 打印电影详情
		if(movieList.size() > 0) {
			System.out.println("电影详情总数：" + movieList.size());
			for(Map<String, String> info : movieList) {
				System.out.println(info.get("name"));
				System.out.println(info.get("href"));
				System.out.println(info.get("imgUrl"));
			}
		}
		return movieList;
	}
	
	/**
	 * 获取所有分页电影链接线程池
	 */
	public static void getAllPageLinksExecutor() {
		// 构造一个线程池(核心池数量corePoolSize最好小于最大池数量maximumPoolSize)
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100, 1000, 3, TimeUnit.SECONDS,
				new ArrayBlockingQueue<Runnable>(ALL_PAGES), new ThreadPoolExecutor.DiscardOldestPolicy());

		CountDownLatch latch = new CountDownLatch(ALL_PAGES);

		// TODO 修改分页与开始变量
		for (int i = 1; i <= ALL_PAGES; i++) {
//			String url = i == 1 ? URL_PAGES + i : URL_PAGES + i;
			String url = i == 1 ? URL_PAGES + ".html" : URL_PAGES + "-" + i + ".html";
			try {
				// 产生一个任务，并将其加入到线程池
				threadPoolExecutor.execute(new GetAllPageLinksTask(url, latch, linkList));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			latch.await();
			threadPoolExecutor.shutdown();
			System.out.println("解除阻塞...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("电影链接总数:" + linkList.size());
	}
	
	/**
	 * 获取所有电影详情线程池
	 */
	public static void getAllMoviesInfoExecutor() {
		// 构造一个线程池(核心池数量corePoolSize最好小于最大池数量maximumPoolSize)
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100, 1000, 3, TimeUnit.SECONDS,
				new ArrayBlockingQueue<Runnable>(linkList.size()), new ThreadPoolExecutor.DiscardOldestPolicy());

		CountDownLatch latch = new CountDownLatch(linkList.size());

		for (int i = 0; i < linkList.size(); i++) {
			try {
				// 产生一个任务，并将其加入到线程池
				threadPoolExecutor.execute(new GetAllMovieLinksTask(linkList.get(i), latch, movieList));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			latch.await();
			threadPoolExecutor.shutdown();
			System.out.println("解除阻塞...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("分页电影链接总数:" + linkList.size());
	}
	
}

/**
 * 获取所有分页电影链接
 * @author fzh
 */
class GetAllPageLinksTask implements Runnable, Serializable {
	private static final long serialVersionUID = 0;
	// 每页的链接
	private String url;
	// 计算器
	private CountDownLatch latch;
	// 保存每页的电影链接
	private List<String> linkList;

	/**
	 * 线程任务构造方法
	 * @param url
	 * @param latch
	 * @param linkList
	 */
	public GetAllPageLinksTask(String url, CountDownLatch latch, List<String> linkList) {
		this.url = url;
		this.latch = latch;
		this.linkList = linkList;
	}

	/**
	 * 具体执行的任务
	 */
	public void run() {
		try {
			// 分页获取电影链接
			getLinksByPage(url);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("分页获取电影 计数器: " + latch.getCount());
			latch.countDown();
		}
	}

	/**
	 * 分页获取电影链接
	 * @param url
	 * @return
	 */
	public void getLinksByPage(String url) {
		// TODO 修改电影域名
//		String DOMAIN = "http://www.kdyy.cc";
		String DOMAIN = "https://www.qiyidy.net";
		try {
			Document doc = Jsoup.connect(url).userAgent(
					"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31")
					.timeout(30000).get();
			// TODO 修改抓取样式
			// http://www.kdyy.cc
//			Elements elements = doc.select("div[class=hy-video-list] ul li a");
			// https://www.qiyidy.net/frim/15-2.html
			Elements elements = doc.select("ul[class=stui-vodlist clearfix] li a[class=stui-vodlist__thumb lazyload]");
			for (Element e : elements) {
				String href = DOMAIN + e.attr("href").trim();
				linkList.add(href);
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

}

/**
 * 获取所有电影详情
 * @author fzh
 */
class GetAllMovieLinksTask implements Runnable, Serializable {
	private static final long serialVersionUID = 0;
	// TODO 修改电影域名
//	private static String DOMAIN = "http://www.kdyy.cc";
	private static String DOMAIN = "https://www.qiyidy.net";
	// 每页的链接
	private String url;
	// 计算器
	private CountDownLatch latch;
	// 保存所有电影详情
	List<Map<String, String>> mvList = new ArrayList<>();

	/**
	 * 线程任务构造方法
	 * @param url
	 * @param latch
	 * @param mvList
	 */
	public GetAllMovieLinksTask(String url, CountDownLatch latch, List<Map<String, String>> mvList) {
		this.url = url;
		this.latch = latch;
		this.mvList = mvList;
	}

	/**
	 * 具体执行的任务
	 */
	public void run() {
		try {
			getMoviesInfo(url);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("获取电影详情 计数器: " + latch.getCount());
			latch.countDown();
		}
	}

	/**
	 * 获取电影详情
	 * @param url
	 * @return
	 */
	public void getMoviesInfo(String url) throws IOException {
		Map<String, String> map = new HashMap<>();
		Document doc = Jsoup.connect(url).userAgent(
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31")
				.timeout(30000).get();
		// TODO 抓取详情样式
		// http://www.kdyy.cc
		/*// 播放链接
		String href = doc.select("dl[class=content] a[class=videopic]").attr("href").trim();
		// 电影标题
		String name = doc.select("dl[class=content] a[class=videopic]").attr("title").trim();
		// 电影图片
		String imgUrl = doc.select("dl[class=content] a[class=videopic]").attr("style").trim();
			   imgUrl = imgUrl.substring(imgUrl.indexOf("(") + 1, imgUrl.indexOf(")"));
		// 电影简介
		String digest = doc.select("div[class=plot] strong").text();
		
		// 电影主演
		String mainText = null;
		Elements elements = doc.select("dl[class=content] ul li");
		for (Element element : elements) {
			if(element.text().contains("主演")) {
				mainText = element.select("a").text();
				break;
			}
		}*/
		
		// https://www.qiyidy.net --- 
		// 播放链接
		String href = doc.select("div[class=stui-content__thumb] a[class=stui-vodlist__thumb picture v-thumb]").attr("href").trim();
		// 电影标题
		String name = doc.select("div[class=stui-content__thumb] a[class=stui-vodlist__thumb picture v-thumb]").attr("title").trim();
		// 电影图片
		String imgUrl = doc.select("div[class=stui-content__thumb] a[class=stui-vodlist__thumb picture v-thumb] img").attr("data-original").trim();
		// 电影简介
		String digest = doc.select("div[class=stui-content__thumb] a[class=stui-vodlist__thumb picture v-thumb] span[class=pic-text text-right]").text();
		
		// 电影主演
		String mainText = null;
		@SuppressWarnings("unused")
		String operator = null;
		Elements elements = doc.select("div[class=stui-content__detail] p[class=data]");
		for (Element element : elements) {
			if(element.text().contains("主演")) {
				mainText = element.text();
			}
			if(element.text().contains("地区")) {
				String html = element.text();
				operator = html.substring(html.indexOf("地区： ") + 4, html.indexOf("年份"));
				break;
			}
		}
		
		map.put("name", name);
		map.put("href", DOMAIN + href);
		map.put("imgUrl", imgUrl);
		map.put("digest", digest);
		map.put("operator", "韩国");
		map.put("mainText", mainText);
		
		mvList.add(map);
	}

}
